﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using CommonLibrary.Data;

namespace CommonLibrary
{
    public static class BankClass
    {
        /// <summary>
        /// 按StringComparer.Ordinal生成SortedDictionary
        /// </summary>
        /// <param name="in_dic"></param>
        /// <returns></returns>
        public static SortedDictionary<string, string> MakeSortedDictionary(this IDictionary<string, string> in_dic)
        {
            SortedDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(StringComparer.Ordinal);
            foreach (KeyValuePair<string, string> keyValuePair in in_dic)
            {
                sortedDictionary.Add(keyValuePair.Key, keyValuePair.Value);
            }
            return sortedDictionary;
        }

        /// <summary>
        /// 把数组所有元素，按照“参数=参数值”的模式用“|”字符拼接成字符串
        /// </summary>
        /// <param name="sArray">需要拼接的数组</param>
        /// <returns>拼接完成以后的字符串</returns>
        public static string CreateSignString(this IDictionary<string, string> dicArray)
        {
            if (dicArray.Count == 0)
            {
                return "";
            }
            StringBuilder prestr = new StringBuilder();
            foreach (KeyValuePair<string, string> temp in dicArray)
            {
                prestr.Append("|" + temp.Key + "=" + temp.Value);
            }

            return prestr.ToString().Substring(1);
        }


        /// <summary>
        ///把数组所有元素，按照“参数=参数值”的模式用"&amp;"字符拼接成字符串 
        /// </summary>
        /// <param name="dicArray">需要拼接的数组</param>
        /// <returns>拼接完成以后的字符串</returns>
        public static string CreateLinkGetString(this IDictionary<string, string> dicArray, Encoding in_Encoding)
        {
            if (dicArray.Count == 0)
            {
                return "";
            }
            StringBuilder prestr = new StringBuilder();
            foreach (KeyValuePair<string, string> temp in dicArray)
            {
                if (in_Encoding == null)
                {
                    prestr.Append("&" + temp.Key + "=" + HttpUtility.UrlEncode(temp.Value));
                    continue;
                }

                prestr.Append("&" + temp.Key + "=" + HttpUtility.UrlEncode(temp.Value, in_Encoding));
            }

            return prestr.ToString().Substring(1);
        }

        /// <summary>
        ///把数组所有元素，按照“参数=参数值”的模式用"&amp;"字符拼接成字符串 
        /// </summary>
        /// <param name="dicArray">需要拼接的数组</param>
        /// <returns>拼接完成以后的字符串</returns>
        public static string CreateLinkGetString(this IDictionary<string, string> dicArray)
        {
            return CreateLinkGetString(dicArray, null);
        }




        /// <summary>
        /// 生成签名结果
        /// </summary>
        /// <param name="sArray">要签名的数组</param>
        /// <param name="key">安全校验码</param>
        /// <param name="sign_type">签名类型</param>
        /// <param name="_input_charset">编码格式</param>
        /// <returns>签名结果字符串</returns>
        public static string BuildMySign(this IDictionary<string, string> dicArray, string key, string sign_type, Encoding in_Encoding)
        {
            Dictionary<string, string> dictionaryParaFilter = ParaFilter(dicArray);//过滤signmsg，并排序

            string prestr = CreateSignString(dictionaryParaFilter);  //把数组所有元素，按照“参数=参数值”的模式用“|”字符拼接成字符串

            prestr = prestr + "|key=" + key;                      //把拼接后的字符串再与安全校验码直接连接起来
            string mysign = Sign(prestr, sign_type, in_Encoding);	//把最终的字符串签名，获得签名结果

            return mysign;
        }


        /// <summary>
        /// 除去数组中的空值和签名参数并以字母a到z的顺序排序
        /// </summary>
        /// <param name="dicArrayPre">过滤前的参数组</param>
        /// <returns>过滤后的参数组</returns>
        public static Dictionary<string, string> ParaFilter(this IDictionary<string, string> dicArrayPre)
        {
            //modi by jian 2013-05-15，强制转换为按StringComparer.Ordinal生成SortedDictionary
            SortedDictionary<string, string> sortedDictionary = MakeSortedDictionary(dicArrayPre);

            Dictionary<string, string> dicArray = new Dictionary<string, string>();
            foreach (KeyValuePair<string, string> temp in sortedDictionary)
            {
                if (temp.Value != null)
                {
                    //if (temp.Key.ToLower() != "sign" && temp.Key.ToLower() != "sign_type" && temp.Value.Trim() != "" && temp.Key.ToLower() != "signmsg")  //过滤数组
                    if (temp.Value.Trim() != "" && temp.Key.ToLower() != "signmsg")  //过滤数组
                    {
                        dicArray.Add(temp.Key.ToString(), temp.Value);
                    }
                }
            }

            return dicArray;
        }


        /// <summary>
        /// 签名字符串
        /// </summary>
        /// <param name="prestr">需要签名的字符串</param>
        /// <param name="sign_type">签名类型</param>
        /// <param name="_input_charset">编码格式</param>
        /// <returns>签名结果</returns>
        public static string Sign(string prestr, string sign_type, Encoding in_Encoding)
        {
            StringBuilder sb = new StringBuilder(32);
            if (sign_type.ToUpper() == "MD5")
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] t = md5.ComputeHash(in_Encoding.GetBytes(prestr));
                for (int i = 0; i < t.Length; i++)
                {
                    sb.Append(t[i].ToString("x").PadLeft(2, '0'));
                }
            }
            else
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                byte[] t = sha1.ComputeHash(in_Encoding.GetBytes(prestr));
                for (int i = 0; i < t.Length; i++)
                {
                    sb.Append(t[i].ToString("x").PadLeft(2, '0'));
                }
            }
            return sb.ToString().ToUpper();
        }





        /// <summary>
        /// 生成签名结果
        /// </summary>
        /// <param name="sArray">要签名的数组</param>
        /// <param name="key">安全校验码</param>
        /// <returns>签名结果字符串</returns>
        public static string BuildMySign(this IDictionary<string, string> dicArray, string key)
        {
            return BuildMySign(dicArray, key, "MD5", Encoding.UTF8);
        }

    }
}
